package main;

import java.io.Serializable;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.PriorityQueue;
import java.util.Set;
import java.util.Map.Entry;


public class Parser {




	   //private static final long MAX_T = 9223372036854775807;
	  /**
	   * Factor for converting nanoseconds to milliseconds.
	   */
	//  private static final double NANO_TO_MILLIS = 1000000;

       /**
	   * Field to hold the Variable for my_reader.
	   * */
	 // private static TxtFileParser my_reader;
	  /**
	   *Field to hold the Variable for my_wordlist.
	   * 
	   */
	  private static List<String> my_wordlist;
	  /**
	   * 
	   * Field to hold the Variable for my_map.
	   */
	 private static Map<String, Integer> my_map;

	  /**
	   * Field to hold the Variable for my_total.
	   * */
	  private static int my_total;

	  
	  
	  private String[] my_keyWordList;
	  /**
	   * Field to hold the deliminator [,].
	   * */
	  private static final String DELIMS = "[\\W\\s$]";


	  /**
	   * Class Field to hold the counter for number of?.
	   * */
	  private int my_counter;

	  /**
	   * @param the_filename holds a parameter for the file name.
	   * 
	   * */
	  public Parser(List<String> the_List, String[] the_keyWordList) {
	    my_keyWordList = the_keyWordList;
	    my_counter = 0;
	    my_map = new HashMap<String, Integer>();
	  }

	  /**
	   * 
	   * @param the_word the word.
	   * @param the_map the map.
	   */
	  
	  public void addMap(final String the_word) {

	    int temp = 0;
	    if (my_map.containsKey(the_word)) {
	      temp = my_map.get(the_word).intValue();
	      temp += 1;
	      my_map.put(the_word, temp);
	    } else {
	      my_map.put(the_word, 1);
	    }
	  }

	
	  /**
	   * maxHeap creates a max heap from the JCL PriorityQueue Class in the API.
	   * @return returns a Maxheap with a default value of size of ten.
	   * */
	  public PriorityQueue<Map.Entry<String, Integer>> createMaxHeap() {
	    final PriorityQueue<Map.Entry<String, Integer>> maxheap = 
	        new PriorityQueue<Map.Entry<String, Integer>>(10, 
	            Collections.reverseOrder(new ProcessComparator()));

	    return maxheap;
	  }

   public int getTotal(){
	   return my_total;
   }
   
//TODO We can do without this since we are using the report
	  /**
	   * getAnalytics method entry point for the program.
	   * @param the_args parameter for the arguments of the main method, 
	   * won't be used for this project.
	   */
	public Map<String, Integer> getAnalytics(List<String> the_text){

	    try {

	      my_wordlist = getWordList(the_text);
	    } catch (final InputOutputException ex) {
	      ex.getMessage();
	    }

	    my_total = my_wordlist.size();
	    final Map<String, Integer> var_map = new HashMap<String, Integer>();

	    for (int i = 0; i < my_wordlist.size(); i++) {

	      addMap(my_wordlist.get(i));
	    }

	    /** Analytics***/

	    /** Word Frequency*/
	  
	//    System.out.println("Total Words: " +my_total+"\n");
	//    System.out.println("Keyword  Average Hits per page Total Hits \n");
	    for (int k = 0; k < my_keyWordList.length; k++){
	    	if (my_map.containsKey(my_keyWordList[k])){
	    	int var_tempCount = my_map.get(my_keyWordList[k]);
	    	 var_map.put(my_keyWordList[k],var_tempCount);
	    	// System.out.println(my_keyWordList[k] +"  "  + var_tempCount);
	    	}
	    }

	 //   return var_map;

	   return my_map;
	  }


	  /**Static inner class to implement comparable on Node Objects.
	   * 
	   * */
	  public static class ProcessComparator implements Comparator<Entry<String, Integer>>
	    , Serializable {

	    /**
	     * Default Serial ID.
	     */
	    private static final long serialVersionUID = 1L;

	    /**
	     * Compare method uses the compare from the Process Node Class.
	     * @param the_first takes a parameter of type ProcessNode<Process> a Job process.
	     * @param the_second the node to compare the first to.
	     * @return returns an integer value for the Node 1 if greater, and -1 if it is less. 
	     * */
	    @Override
	    public int compare(final Entry<String, Integer> the_first, final Entry<String, 
	                       Integer> the_second) {

	      return Double.compare(the_first.getValue(), the_second.getValue());
	    }
	  };


	  /**
	   * Method to create the process by reading input from a file.
	   * @return returns a Process List
	   * @throws InputOutputException this method will throw an exception if it cannot
	   * read the file or write to it.
	   * */
	  public List<String> getWordList(List<String> the_text) throws InputOutputException {
		 // List<String> var_tlist = the_text;
		  List<String> var_tlist = new ArrayList<String>();
	    String[] tokens = null;
	   /*
	     Iterator<String> s = my_tlist.iterator();

	      while (s.hasNext()) {

	        tokens = s.next().split(DELIMS); //(s.next());
	    */
	    
	    for (int j = 0; j< the_text.size(); j++){
	    	tokens = the_text.get(j).split(DELIMS); //(s.next());
	    	
	    	
	        for (int i = 0; i < tokens.length; i++) {

	          final String temp2  = tokens[i].toLowerCase(); 
	          tokens[i] = temp2;
	          if (!(tokens[i].length() == 0)) {
	        	  var_tlist.add(my_counter, tokens[i]);
	            my_counter++;
	          } 
	        }

	      }


	    return var_tlist;




	  }
}
